﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.ComponentModel;

namespace WebPALTT.Lib
{
    /*
     * Class: ActionItem_If
     *  
     * This class represents an if statement action and inherits from @link[ActionItem.cs.htm, ActionItem]. 
     */
    [Serializable]
    public class ActionItem_If : ActionItem
    {
        public override ActionType ActionType { get { return ActionType.If; } }

        string mCondition;
        ActionItemCollection mThenActions;
        ActionItemCollection mElseActions;

        /*
         * Name: Properties
         * 
         * /string/ Condition:
         * 
         * Gets or sets the condition to evaluate for this action.
         * 
         * ++NB: Changing the condition during runtime (from a script action) will not affect the outcome.++
         * 
         * /@link[ActionItemCollection.cs.htm, ActionItemCollection]/ ThenActions:
         * 
         * Gets the action item collection to loop through if the condition is true.
         *
         * /@link[ActionItemCollection.cs.htm, ActionItemCollection]/ ElseActions:
         * 
         * Gets the action item collection to loop through if the condition is false.
         */

        /// <summary>
        /// Gets or sets the condition to evaluate for this action.
        /// NB: Changing the condition during runtime (from a script action) will not affect the outcome. 
        /// </summary>
        [DescriptionAttribute("Condition to evaluate at runtime.\nNB: while the condition is evaluated at runtime it cannot be changed at runtime.")]
        [Editor(typeof(System.ComponentModel.Design.MultilineStringEditor), typeof(System.Drawing.Design.UITypeEditor))]
        public string Condition { get { return mCondition; } set { mCondition = value; } }
        /// <summary>
        /// Gets or sets the action item collection to run if the condition is true.
        /// </summary>
        [BrowsableAttribute(false)]
        public ActionItemCollection ThenActions { get { return mThenActions; } }
        /// <summary>
        /// Gets or sets the action item collection to run if the condition is false.
        /// </summary>
        [BrowsableAttribute(false)]
        public ActionItemCollection ElseActions { get { return mElseActions; } }

        public ActionItem_If(string name) : this(name, "true", null, null) { }

        public ActionItem_If(string name, string condition, ActionItemCollection thenactions, ActionItemCollection elseactions)
            : base(name)
        {
            mCondition = condition;
            mThenActions = thenactions == null ? new ActionItemCollection() : thenactions;
            mElseActions = elseactions == null ? new ActionItemCollection() : elseactions;
        }

        public ActionItem_If(SerializationInfo info, StreamingContext ctxt)
            : base(info, ctxt)
        {
            mCondition = (string)info.GetValue("Condition", typeof(string));
            mThenActions = (ActionItemCollection)info.GetValue("ThenActions", typeof(ActionItemCollection));
            mElseActions = (ActionItemCollection)info.GetValue("ElseActions", typeof(ActionItemCollection));
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            base.GetObjectData(info, ctxt);
            info.AddValue("Condition", mCondition);
            info.AddValue("ThenActions", mThenActions);
            info.AddValue("ElseActions", mElseActions);
        }

        public override string[] Validate()
        {
            List<string> errors = new List<string> { };
            if (Name.Equals("Then") || Name.Equals("Else") || Name.Equals("Actions"))
                errors.Add("Error: action[" + Name + "(" + ActionType + ")] is using a reserverd name.");
            if (Name.IndexOfAny(new char[] { ' ', '(', ')', '[', ']', '{', '}', ';', ':', '.', ',', '\\', '/' }) > -1)
                errors.Add("Error: action[" + Name + "(" + ActionType + ")].Name contains invalid characters.");

            if (ThenActions.Count == 0 && ElseActions.Count == 0)
                errors.Add("Warning: action[" + Name + "(" + ActionType + ")]. - Conditional action doesn't contain any sub actions");
            foreach (ActionItem action in ThenActions)
                errors.AddRange(action.Validate());
            foreach (ActionItem action in ElseActions)
                errors.AddRange(action.Validate());

            return errors.ToArray();
        }

        public override void SetParent(ActionItem parent, int index = 0)
        {
            base.SetParent(parent, index);
            for (int i = 0; i < mThenActions.Count; i++)
                mThenActions[i].SetParent(this, i);
            for (int j = 0; j < mElseActions.Count; j++)
                mElseActions[j].SetParent(this, j);
        }

        public override ActionItem GetChild(Guid key)
        {
            if (mThenActions.Contains(key, true))
                return mThenActions.GetChild(key);
            if (mElseActions.Contains(key, true))
                return mElseActions.GetChild(key);
            return null;
        }
    }
}
